package com.liliudong.pinkyponk.api.admin.security;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.liliudong.pinkyponk.biz.sys.entity.SysUser;
import com.liliudong.pinkyponk.biz.sys.enums.SysRoleDataScope;
import com.liliudong.pinkyponk.biz.sys.enums.SysUserStatus;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * UserDetails
 *
 * @author liliudong
 * @date 2022-05-27 15:38
 **/
public class UserDetailsImpl implements UserDetails {

    private final SysUser sysUser;
    private final Set<GrantedAuthority> roleSet;
    private final Set<GrantedAuthority> authoritySet;
    private final Set<Integer> dataScopes;
    private final Set<String> orgNos;

    public UserDetailsImpl(SysUser sysUser, Set<GrantedAuthority> roleSet,
                           Set<GrantedAuthority> authoritySet, Set<Integer> dataScopes, Set<String> orgNos) {
        this.sysUser = sysUser;
        this.roleSet = roleSet;
        this.authoritySet = authoritySet;
        this.dataScopes = dataScopes;
        this.orgNos = orgNos;

    }

    public boolean isSuperUser() {
        return dataScopes.contains(SysRoleDataScope.ALL.scope);
    }

    public SysUser getSysUser() {
        return sysUser;
    }

    public Set<String> getOrgNos() {
        return orgNos;
    }

    public Long getUserId() {
        return getSysUser().getId();
    }

    public String getCurrentOrgNo() {
        return getSysUser().getOrgNo();
    }

    public Set<Integer> getDataScopes() {
        return dataScopes;
    }

    public Set<String> getRoleCodeSet() {
        if (CollectionUtil.isEmpty(roleSet)) {
            return Set.of();
        }
        return roleSet.stream().map(GrantedAuthority::getAuthority).collect(Collectors.toSet());
    }

    public Set<String> getAuthoritySet() {
        if (CollectionUtil.isEmpty(authoritySet)) {
            return Set.of();
        }
        return authoritySet.stream().map(GrantedAuthority::getAuthority).collect(Collectors.toSet());
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        ArrayList<GrantedAuthority> grantedAuthorities = new ArrayList<>();
        grantedAuthorities.addAll(roleSet);
        grantedAuthorities.addAll(authoritySet);
        return grantedAuthorities;
    }

    @Override
    public String getPassword() {
        return sysUser.getPassword();
    }

    @Override
    public String getUsername() {
        return sysUser.getUsername();
    }

    @Override
    public boolean isAccountNonExpired() {
        return sysUser.getExpireTime().after(DateUtil.date());
    }

    @Override
    public boolean isAccountNonLocked() {
        return !sysUser.getStatus().equals(SysUserStatus.LOCKED.status);
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}
